﻿using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate.Linq;
using NHibernate;
using GIC.DAO.Model;

namespace GIC.DAO.Access
{
    public class GICDao
    {
        public void Delete(EntityBase entity)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    session.Delete(entity);
                    transaction.Commit();
                }
            }
        }

        public EntityBase Update(EntityBase poEntity)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    session.SaveOrUpdate(poEntity);

                    transaction.Commit();

                    if (poEntity is Parametros)
                    {
                        var entity = (from param in session.Query<Parametros>()
                                      where param.Id == (poEntity.Id)
                                      select param).Single();
                        return entity;
                    }

                    if (poEntity is Chassi)
                    {
                        var entity = (from param in session.Query<Chassi>()
                                      where param.Id == (poEntity.Id)
                                      select param).Single();
                        return entity;
                    }

                    if (poEntity is BodyNoReenvio)
                    {
                        var entity = (from param in session.Query<BodyNoReenvio>()
                                      where param.Id == (poEntity.Id)
                                      select param).Single();
                        return entity;
                    }

                    if (poEntity is EtiquetaChassiLeitor)
                    {
                        var entity = (from param in session.Query<EtiquetaChassiLeitor>()
                                      where param.Id == (poEntity.Id)
                                      select param).Single();
                        return entity;
                    }

                    return null;
                }
            }
        }

        public EntityBase Create(EntityBase poEntity)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    var retorno = session.Save(poEntity);

                    transaction.Commit();

                    EntityBase entity = new EntityBase();
                    entity.Id = (int)retorno;

                    return this.GetById(entity);
                }
            }
        }

        public EntityBase GetById(EntityBase poEntity)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                if (poEntity is Parametros)
                {
                    var entidade = (from param in session.Query<Parametros>()
                                    where param.Id == (poEntity.Id)
                                    select param).Single();
                    return entidade;
                }
                if (poEntity is Chassi)
                {
                    var entidade = (from param in session.Query<Chassi>()
                                    where param.Id == (poEntity.Id)
                                    select param).Single();
                    return entidade;
                }

                return null;
            }
        }

        public Parametros obterParametros()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var entidade = (from param in session.Query<Parametros>()
                                select param).FirstOrDefault();

                return entidade;
            }
        }

        public Chassi obterChassis(Chassi chassiEntity)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var entidade = (from chassi in session.Query<Chassi>()
                                where chassi.bodyNumber.Equals(chassiEntity.bodyNumber.Replace("*", ""))
                                select chassi).FirstOrDefault();

                return entidade;
            }
        }

        public List<Chassi> listarChassiImpresso(Boolean impresso)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                if (impresso)
                {
                    var entidade = (from chassi in session.Query<Chassi>()
                                    where chassi.impresso == 1
                                    select chassi).ToList();

                    return entidade;
                }
                else
                {
                    var entidade = (from chassi in session.Query<Chassi>()
                                    where chassi.impresso == 0
                                    select chassi).ToList();

                    return entidade;
                }
            }
        }

        public void deletarChassiPorData(DateTime dataRemocao)
        {

            DateTime inicio = dataRemocao.AddHours(-dataRemocao.Hour).AddMinutes(-dataRemocao.Minute).AddSeconds(-dataRemocao.Second).AddMilliseconds(-dataRemocao.Millisecond);
            DateTime fim = inicio.AddHours(23).AddMinutes(59).AddSeconds(59).AddMilliseconds(999);

            inicio = inicio.AddHours(-48);

            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    IQuery query = session.CreateQuery("DELETE Chassi where (reportDate not between :inicio and :fim) or reportDate is null");

                    query.SetDateTime("inicio", inicio);
                    query.SetDateTime("fim", fim);

                    query.ExecuteUpdate();

                    transaction.Commit();
                }
            }
        }

        public void deletarTodosChassis()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    IQuery query = session.CreateQuery("DELETE FROM Chassi");
                    query.ExecuteUpdate();
                    transaction.Commit();
                }
            }
        }

        public void deletarSocketPorData(DateTime dataRemocao)
        {

            DateTime inicio = dataRemocao.AddHours(-dataRemocao.Hour).AddMinutes(-dataRemocao.Minute).AddSeconds(-dataRemocao.Second).AddMilliseconds(-dataRemocao.Millisecond);
            DateTime fim = inicio.AddHours(23).AddMinutes(59).AddSeconds(59).AddMilliseconds(999);

            inicio = inicio.AddHours(-48);

            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    IQuery query = session.CreateQuery("DELETE SocketHyundai where (dataOcorrencia not between :inicio and :fim) or dataOcorrencia is null");

                    query.SetDateTime("inicio", inicio);
                    query.SetDateTime("fim", fim);

                    query.ExecuteUpdate();

                    transaction.Commit();
                }
            }
        }

        public SocketHyundai recuperarUltimoSocket()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var entidade = (from socketHyundai in session.Query<SocketHyundai>() orderby socketHyundai.dataOcorrencia descending
                                select socketHyundai);
                try
                {
                    return entidade.First();
                }
                catch (Exception e) { return null; }
            }
        }

        public BodyNoReenvio recuperarSocketPendente()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var entidade = (from socketPendente in session.Query<BodyNoReenvio>()
                                orderby socketPendente.Data descending
                                select socketPendente);
                try
                {
                    return entidade.First();
                }
                catch (Exception e) { return null; }
            }
        }

        public BodyNoReenvio[] atualizarSocketReenvio(String BodyNo)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var entidade = (from socketPendente in session.Query<BodyNoReenvio>()
                                where socketPendente.BodyNo == BodyNo && socketPendente.Status == Enum.GetName(typeof(StatusBodyNoReenvio), StatusBodyNoReenvio.Pendente)
                                select socketPendente);
                try
                {
                    return entidade.ToArray();
                }
                catch (Exception e) { return null; }
            }
        }

        public void deletarSocketReenvioPendente(String BodyNo)
        {
            String status = Enum.GetName(typeof(StatusBodyNoReenvio), StatusBodyNoReenvio.Pendente);

            using (var session = NHibernateHelper.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    IQuery query = session.CreateQuery("DELETE BodyNoReenvio where BodyNo = :BodyNo and Status = :status");

                    query.SetParameter("BodyNo", BodyNo);
                    query.SetParameter("status", status);

                    query.ExecuteUpdate();

                    transaction.Commit();
                }
            }
        }

        public String obterSenha()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var entidade = (from param in session.Query<Senha>()
                                select param).FirstOrDefault();

                return entidade.SenhaTxt;
            }
        }

        public List<EtiquetaChassiLeitor> listarChassiLeitor()
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var entidade = (from param in session.Query<EtiquetaChassiLeitor>()
                                select param).ToList();

                return entidade;
            }
        }

        public EtiquetaChassiLeitor recuperarEtiquetaChassiLeitorExistentePeloCodigoEtiqueta(string codEti)
        {
            using (var session = NHibernateHelper.OpenSession())
            {
                var entidade = (from x in session.Query<EtiquetaChassiLeitor>()
                                where x.CodigoEtiqueta == codEti
                                select x);
                try
                {
                    return entidade.First();
                }
                catch (Exception e) { return null; }
            }
        }
    }
}
